#pragma once

#include<iostream>
#include<queue>
#include<pthread.h>
#include<vector>
using namespace std;
template<class T>
class BlockQueue
{
    static const int defaultnum=20;
public:
    BlockQueue(int maxcap = defaultnum)
        :maxcap_(maxcap)
    {
        pthread_mutex_init(&mutex_, nullptr);
        pthread_cond_init(&c_cond_, nullptr);
        pthread_cond_init(&p_cond_, nullptr);
    }
    T pop()
    {
        pthread_mutex_lock(&mutex_);
        while(q_.size()==0){
             pthread_cond_wait(&c_cond_,&mutex_);
        }
        T num=q_.front();
        q_.pop();
        pthread_cond_signal(&p_cond_);
        pthread_mutex_unlock(&mutex_);
        return num;
    }
    void push(T &in,string name)
    {
        pthread_mutex_lock(&mutex_);
        while(q_.size()==maxcap_){
            pthread_cond_wait(&p_cond_,&mutex_);
        }
        q_.push(in);
        cout <<name<< "生产了一个数据: "<<in.getTask()<< endl;
        pthread_cond_signal(&c_cond_);
        pthread_mutex_unlock(&mutex_);
    }
    ~BlockQueue()
    {
        pthread_mutex_destroy(&mutex_);
        pthread_cond_destroy(&c_cond_);
         pthread_cond_destroy(&p_cond_);
    }

private:
    queue<T> q_;
    int maxcap_;//极值
    pthread_mutex_t mutex_;
    pthread_cond_t c_cond_;//条件变量
    pthread_cond_t p_cond_;//条件变量
};